﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using MathNet.Numerics;
using System.Collections;

namespace ParticleTracker.Utilities
{
    public delegate Complex complexOp(Complex target);

   static class ArrayOps
    {
        //uses generic type "T" that means this method can be used with any type of object.
        public static void setRow<T>(int index, T[,] target, T[] row) 
        {
            //Console.WriteLine(target.GetLength(0) + "   " + target.GetLength(1));
            if (target.GetLength(1).Equals(row.GetLength(0)))
            {
                for (int i = 0; i < Math.Max(target.GetLength(1),row.GetLength(0)); i++)
                {
                    target[index, i] = row[i];
                }
            }
        }

        public static void setColumn<T>(int index, T[,] target, T[] row)
        {
            if (target.GetLength(0).Equals(row.GetLength(0)))
            {
                
                for(int i = 0; i<Math.Max(target.GetLength(0),row.GetLength(0)); i++)
                {
                    target[i,index] = row[i];
                }
            }  
        }

        public static T[] getRow<T>(int index, T[,] target)
        {
            T[] row = new T[target.GetLength(1)];
            for(int i = 0; i<target.GetLength(1);i++)
            {
                row[i] = target[index,i];
            }
            return row;
        }

        public static T[] getColumn<T>(int index, T[,] target)
        {
            T[] column = new T[target.GetLength(0)];
            for(int i = 0; i<target.GetLength(0);i++)
            {
                column[i] = target[i,index];
            }
            return column;
        }

        public static void printArray<T>(T[] target)
        {
            foreach (T i in target)
            {
                Console.Write(i+ ", ");
            }
            Console.Write("\n");
        }
        public static void printArray<T>(T[,] target)
        {
            for (int i = 0; i < target.GetLength(0); i++)
            {
                printArray(getRow(i, target));
            }
        }

        public static string array2Str<T>(T[] target)
        {
            string str = "";
            foreach (T i in target)
            {
                str = str + i.ToString() + ", ";
            }
            return str;
        }

        public static Complex[,] pointwiseMultiply(Complex[,] a, Complex[,] b)
        {
            int rowDim = Math.Max(a.GetLength(0),b.GetLength(0));
            int colDim = Math.Max(a.GetLength(1),b.GetLength(1));
            Complex[,] product = new Complex[rowDim,colDim];

            for(int i = 0; i<rowDim; i++)
            {
                for(int j = 0; j<colDim; j++)
                {
                    product[i,j] = a[i,j]*b[i,j];
                }
            }
            return product;
                    
        }
        
        public static Complex[,] pointwiseOperation(Complex[,] a, complexOp operation)
        {
            for (int i = 0; i < a.GetLength(0); i++)
            {
                for (int j = 0; j < a.GetLength(1); j++)
                {
                    a[i, j] = operation(a[i,j]);
                }
            }
            return a;

        }

        public static T[,] getRegion<T>(T[,] array, int startRow, int numRows, int startCol, int numCols)
        {
            T[,] subArray = new T[numRows, numCols];

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numCols; j++)
                {
                    subArray[i, j] = array[startRow + i, startCol + j];
                }
            }
            return subArray;

        }

        public static T[,] getRegion<T>(T[,] array, Rectangle r)
        {
            return getRegion(array, r.X, r.Width, r.Y, r.Height);
        }

        public static T[,] arrayListToArray<T>(ArrayList col1, ArrayList col2)
        {
            T[] col1array = (T[])col1.ToArray(typeof(T));
            T[] col2array = (T[])col2.ToArray(typeof(T));
            T[,] array = new T[col1.Count, 2];
            ArrayOps.setColumn(0, array, col1array);
            ArrayOps.setColumn(1, array, col2array);
            return array;
  
        }

        public static bool areArraysEqual(int[] a, int[] b)
        {
            if (a.Length == b.Length)
            {
                for (int i = 0; i < a.Length; i++)
                {
                    if (a[i] != b[i])
                    {
                        return false;
                    }
                }
                return true;
            }
            else
            {
                return false;
            }
        }

    }
}
